package com.projetosi.web.server.sistema.objetos;


import java.io.Serializable;

import com.projetosi.web.server.sistema.interfaces.IGenericObject;
import com.projetosi.web.server.sistema.util.Data;

/**
 * 
 * @author Felipe Jose, Filipe Alencar, Rodrigo de Brito, Thiago Goncalves, Victor Hugo Arcelino;
 *
 */
public class Emprestimo implements IGenericObject,Serializable{
	

	/**
	 * 
	 */
	private static final long serialVersionUID = 6876378671035712622L;
	Data dataDeAprovacao;
	private Data dataDeDevolucao;
	private int estimativaDeDuracao, idResquisicaoEmprestimo, idEmprestimo;
	private Usuario emprestador, beneficiado;
	private StatusEmprestimo status;
	private Item itemAEmprestar;
	

	/**
	 * Cria um objeto do tipo Emprestimo.
	 * @param beneficiado O usuario que requisita o emprestimo do item.
	 * @param emprestador O usuario que emprestara o item.
	 * @param estimativaDuracao O tempo estimado da duracao do emprestimo.
	 * @throws Exception Se o o beneficiado ou emprestador for null ou se a estimativa de tempo de duracao do emprestimo for menor ou igual a 0.
	 */
	
	public Emprestimo(Usuario beneficiado, Usuario emprestador, Item itemAEmprestar  , int estimativaDuracao, int idRequisicaoEmprestimo) throws Exception{
		setBeneficiado(beneficiado);
		setEmprestador(emprestador);
		setStatus(StatusEmprestimo.EM_ANDAMENTO);
		setEstimativaDeDuracao(estimativaDuracao);
		setIdRequisicaoEmprestimo(idRequisicaoEmprestimo);
		setItemAEmprestar(itemAEmprestar);
		
	}
	

	
	public enum StatusEmprestimo {
		EM_ANDAMENTO("Andamento"), COMPLETADO_SC("Andamento"), CANCELADO("Cancelado"), CANCELADO_ANTES_TEMPO("Cancelado antes do tempo"), COMPLETADO("Completado");
		
		private String status;
		
		private StatusEmprestimo(String status) {
			setStatus(status);
		}
		
		public String getNomeStatus() {
			return status;
		}
		
		public void setStatus(String status) {
			this.status = status;
		}
	}
	
	
	/**
	 * Calcula a data de devolucao do item emprestado.
	 * @return A data de devolucao.
	 */
	Data calculaDataDevolucao(){
		Data dataDevolucao = new Data(getDataDeAprovacao().dataFormatada());
		dataDevolucao.addDias(getEstimativaDeDuracao());
		return dataDevolucao;
	}
	/**
	 * Retorna a data de aprovacao do emprestimo.
	 * @return A data de aprovacao.
	 */
	public Data getDataDeAprovacao() {
		return dataDeAprovacao;
	}
	
	/**
	 * Altera a data de aprovacao do emprestimo.
	 * @param date A nova data de aprovacao.
	 */
	public void setDataDeAprovacao(Data date) {
		this.dataDeAprovacao = date;
	}

	/**
	 * Retorna a data de devolucao do item emprestado.
	 * @return
	 */
	public Data getDataDeDevolucao() {
		return dataDeDevolucao;
	}
	/**
	 * Altera a data de devolucao do item emprestado,
	 * @param dataDeDevolucao A nova data de devolucao.
	 */
	public void setDataDeDevolucao(Data dataDeDevolucao) {
		this.dataDeDevolucao = dataDeDevolucao;
	}

	/**
	 * Retorna o tempo de duracao estimado do emprestimo.
	 * @return O tempo de duracao do emprestimo.
	 */
	public int getEstimativaDeDuracao() {
		return estimativaDeDuracao;
	}

	/**
	 * Altera o tempo de duracao do emprestimo.
	 * @param estimativaDeDuracao O novo tempo de duracao do emprestimo.
	 */
	public void setEstimativaDeDuracao(int estimativaDeDuracao) throws Exception {
		if(estimativaDeDuracao <= 0){
			throw new Exception("Duracao inválida");
		}
		this.estimativaDeDuracao = estimativaDeDuracao;
	}

	/**
	 * Retorna o emprestador.
	 * @return O emprestador.
	 */
	public Usuario getEmprestador() {
		return emprestador;
	}
	
	/**
	 * Altera o emprestador.
	 * @param emprestador O novo emprestador.
	 */
	public void setEmprestador(Usuario emprestador) throws Exception{
		if(emprestador == null){
			throw new Exception("O usuario emprestador nao pode ser nulo!");
		}
		this.emprestador = emprestador;
	}
	
	/**
	 * Retorna o usuario beneficiado pelo emprestimo.
	 * @return O beneficiado
	 */
	public Usuario getBeneficiado() {
		return beneficiado;
	}
	
	/**
	 * Altera o usuario beneficiado.
	 * @param beneficiado O novo beneficiado.
	 */
	public void setBeneficiado(Usuario beneficiado) throws Exception {
		if(beneficiado == null){
			throw new Exception("O usuario beneficiado nao pode ser nulo!");
		}
		this.beneficiado = beneficiado;
	}
	
	/**
	 * Retornam o status do emprestimo.
	 * @return O status do emprestimo.
	 */
	public StatusEmprestimo getStatus() {
		return status;
	}
	
	/**
	 * Altera o status do emprestimo.
	 * @param status O novo status do emprestimo.
	 */
	public void setStatus(StatusEmprestimo status) {
		this.status = status;
	}
	
	/**
	 * Retorna o id de requisicao do emprestimo.
	 * @return o id de requisicao do emprestimo.
	 */
	public int getIdRequisicaoEmprestimo() {
		return idResquisicaoEmprestimo;
	}
	
	/**
	 * Retorna o id do emprestimo.
	 * @return o id do emprestimo.
	 */
	public int getIdEmprestimo() {
		return idEmprestimo;
	}
	
	/**
	 * Altera o id de requisicao do emprestimo.
	 * @param idEmprestimo O novo id do emprestimo.
	 */
	public void setIdRequisicaoEmprestimo(int idEmprestimo) throws Exception {
		if(idEmprestimo <= 0){
			throw new Exception("O id do emprestimo deve ser maior que 0!");
		}
		this.idResquisicaoEmprestimo = idEmprestimo;
	}
	
		
	/**
	 * Altera o id  do emprestimo.
	 * @param idEmprestimo O novo id do emprestimo.
	 */
	public void setidEmprestimo(int idEmprestimo) throws Exception {
		if(idEmprestimo <= 0){
			throw new Exception("O id do emprestimo deve ser maior que 0!");
		}
		this.idEmprestimo = idEmprestimo;
	}
	
	
	
	/**
	 * Retorna o item que está sendo emprestado.
	 * @return - Item
	 */
	public Item getItemAEmprestar() {
		return itemAEmprestar;
	}
	
	/**
	 * Muda o item que está sendo emprestado.
	 * @param itemAEmprestar - Item
	 * @throws Exception
	 */
	public void setItemAEmprestar(Item itemAEmprestar) throws Exception{
		if(itemAEmprestar == null){
			throw new Exception("Informe um item não nulo!");
		}
		this.itemAEmprestar = itemAEmprestar;
	}

	/**
	 * Compara dois objetos do tipo Emprestimo.
	 * @return true: se o emprestimo for o mesmo e false caso contrário.
	 */
	@Override
	public boolean equals(Object obj) {
		if(!(obj instanceof Emprestimo)){
			return false;
		}
		Emprestimo outro = (Emprestimo) obj;
		return (this.idEmprestimo == outro.idEmprestimo);
	}
	
}
